#include <lcir/ADT/Range.h>
#include <lcir/IR/Expression.h>
#include <lcir/IR/Lambda.h>
#include <lcir/IR/Operand.h>
#include <lcir/IR/Prototype.h>
#include <lcir/IR/Value.h>
#include <lcir/IR/ValuePrinter.h>
#include <lcir/IR/Constant.h>
namespace lcir {
Value *Value::getDefExprParent() const {
  auto *def = getDefExpr();
  if (!def) return nullptr;
  return def->getLambda();
}

Value *Value::getRoot() const {
  auto *root = const_cast<Value *>(this);
  // 如果value不是root，找到root
  while (auto *parent = root->getDefExprParent()) {
    root = parent;
  }
  return root;
}

Operand* Value::getSingleUser() {
  for(auto [idx, user] : IndexRange(users)) {
    if(idx > 1) return nullptr;
  }
  return &(*users.begin());
}

void Value::addUser(Operand *operand) { 
  users.pushBack(operand); 
}
void Value::removeUser(Operand *operand) { users.remove(operand); }
void Value::rauw(Value *newValue) {
  size_t idx{0};
  for (auto &user : IncRange(users)) {
     user.setValue(newValue);
   }
}
void Value::setInfo(std::string_view str) {
  if (auto *proto = getProto()) proto->setInfo(str);
}

std::string Value::getInfo() const {
  if (auto *proto = getProto()) return proto->getInfo();
  return "";
}

Constant *Value::tryFold() {
  if(this->isa<Constant>()) {
    return this->dyn_cast<Constant>();
  }
  auto expr = getDefExpr();
  if(!expr) return nullptr;
  return expr->tryFold();
}
}  // namespace lcir